package com.tianyuan.test1;

/**双指针*/

import java.util.Arrays;

/**
 * 移动零
 * 给定一个数组 nums，编写一个函数将所有 0 移动到数组的末尾，同时保持非零元素的相对顺序。
 * 请注意，必须在不复制数组的情况下原地对数组进行操作。
 * @date 2025/10/27 15:08
 * 示例 1:
 * 输入: nums = [0,1,0,3,12]
 * 输出: [1,3,12,0,0]
 * 示例 2:
 * 输入: nums = [0]
 * 输出: [0]
 */
class Solution {
    public void moveZeroes(int[] nums) {
        // 获取数组长度
        int n = nums.length;
        // 左指针：指向当前已经处理好的非零元素的下一个位置（即下一个非零元素应该放置的位置）
        int left = 0;
        // 右指针：用于遍历数组，寻找非零元素
        int right = 0;
        // 遍历整个数组
        while (right < n) {
            // 当右指针找到非零元素时
            if (nums[right] != 0) {
                // 将右指针找到的非零元素与左指针位置的元素交换
                // （左指针位置可能是0，也可能是已处理过的非零元素，交换后非零元素被移到左侧）
                swap(nums, left, right);
                // 左指针右移，指向新的待填充位置
                left++;
            }
            // 无论是否找到非零元素，右指针都右移继续遍历
            right++;
        }
    }
    /**
     * 交换数组中两个位置的元素
     * @param nums 数组
     * @param left 要交换的第一个位置
     * @param right 要交换的第二个位置
     */
    public void swap(int[] nums, int left, int right) {
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }
    /**
     * 思路及解法
     * 使用双指针，左指针指向当前已经处理好的序列的尾部，右指针指向待处理序列的头部。
     * 右指针不断向右移动，每次右指针指向非零数，则将左右指针对应的数交换，同时左指针右移。
     * 注意到以下性质：
     * 1.左指针左边均为非零数；
     * 2.右指针左边直到左指针处均为零。
     * 因此每次交换，都是将左指针的零与右指针的非零数交换，且非零数的相对顺序并未改变。
     */






    public static void main(String[] args) {
        Solution solution = new Solution();

        // 测试用例1
        int[] nums1 = {0, 1, 0, 3, 12};
        System.out.println("测试用例1输入: " + Arrays.toString(nums1));
        solution.moveZeroes(nums1);
        System.out.println("测试用例1输出: " + Arrays.toString(nums1)); // 预期 [1, 3, 12, 0, 0]

        // 测试用例2
        int[] nums2 = {0};
        System.out.println("测试用例2输入: " + Arrays.toString(nums2));
        solution.moveZeroes(nums2);
        System.out.println("测试用例2输出: " + Arrays.toString(nums2)); // 预期 [0]
    }
}